因為感覺在操作上還蠻常用到 array
及 object
的各種方法,所以這篇就來說說 JavaScript 中 array
與 object
的各常用方法,以及 for in
和 for of
。
在 JavaScript 中,當你使用
typeof [1, 2, 3]
會出現
"object"
沒錯,在 JavaScript 中 array
其實也是 object
。
所以在判別兩者時,不能使用 typeof
,而要使用 Array.isArray()
。
// true
Array.isArray(["Charlie", "the", "Unicorn"]);
// false
Array.isArray({
type: "Unicorn",
name: "Charlie"
});
我們每個方法都使用以下陣列做示範:
// 先做一個可憐的白老鼠陣列
let students = ["Jacob", "Pascal", "Jack"];
請想成每個試驗前都重新變成以上狀態。
students.push("Jeromy");
// ["Jacob", "Pascal", "Jack", "Jeromy"]
students.push("Eric", "Peter");
// ["Jacob", "Pascal", "Jack", "Jeromy", "Eric", "Peter"]
let lastOne = student.pop()
// ["Jacob", "Pascal", "Jack", "Jeromy", "Eric"]
// lastOne: "Peter"
push
會在陣列後方加上東西,可以一次加上多項東西。pop
則會移除陣列最後方的一個東西並回傳該東西。
students.unshift("Jeromy");
// ["Jeromy", Jacob", "Pascal", "Jack"]
students.unshift("Eric", "Peter");
// ["Eric", "Peter", "Jeromy", "Jacob", "Pascal", "Jack"]
let firstOne = student.shift()
// ["Peter", "Jeromy", "Jacob", "Pascal", "Jack"]
// firstOne: "Eric"
unshift
會在陣列前方加上東西,可以一次加上多項東西。 值得注意的是,加上多項東西時,它們在陣列中的位置會與傳入的順序相同。shift
則會移除陣列最前方的一個東西並回傳該東西。
let firstTwo = students.slice(0, 2);
// firstTwo: ["Jacob", "Pascal"]
let secondStu = students.slice(1, 2);
// secondStu: ["Pascal"]
let removed = students.splice(0, 1);
// students: ["Pascal", "Jack"]
// removed: ["Jacob"]
students.splice(0, 1, ...removed);
// students: ["Jacob", "Jack"]
slice
會自第一個參數的位置開始至第二個參數的位置前淺拷貝並回傳。不會修改原陣列!
array.slice(start, ?end) // end 未指定會到底
splice
會自第一個參數的位置開始刪除第二個參數數量的元素,再加上後方參數至該位置。會修改原陣列!
array.splice(start, delCount, add1, add2, ...)
let moreStu = ["Peter", "Eric", "Jeromy"];
students = students.concat(moreStu);
// students: ["Jacob", "Pascal", "Jack", "Peter", "Eric", "Jeromy"]
concat
可以合併多陣列,但記得不會修改原陣列!
array.concat(addArray1, addArray2, ...)
students.sort((a, b) => b.length - a.length);
// ["Pascal", "Jacob", "Jack"]
students.reverse();
// ["Jack", "Jacob", "Pascal"]
sort
用來排序陣列,其參數為一個「比較函式」,其有參數 a, b 代表兩個被比較的元素,如果回傳值大於 0 則 b 排在 a 前,反之,a 排在 b 前。此方法直接修改原陣列!
可以想成如果大於 0 則 b 超 a 車跑到前面去
reverse
則是將陣列反過來。此方法直接修改原陣列!
students.forEach((name, idx) => {
console.log(idx, name);
});
// Console:
// 0 "Jacob"
// 1 "Pascal"
// 2 "Jack"
students = students.map(name => {
return "Student " + name;
});
// ["Student Jacob", "Student Pascal", "Student Jack"]
forEach
用來遍歷陣列的值,並對每項進行操作。不修改原陣列且沒有回傳值。
array.forEach((value, index, array) => {
// do something
})
// 沒有回傳值
map
也是用來遍歷陣列的值,並對每項進行修改。不修改原陣列但會回傳經修改過的陣列。
array.map((value, index, array) => {
// do something
// and return new value
})
// 回傳修改後的陣列
let namesWithJ = students.filter(name => name.includes("J"));
// namesWithJ: ["Jacob", "Jack"]
let firstNameWithJ = students.find(name => name.includes("J"));
// firstNameWithJ: "Jacob"
filter
用來過濾陣列中符合條件的值,並回傳該符合條件的陣列。如果判別函式回傳 true
就是符合,反之則是不符合。不修改原陣列。
array.filter((value, index, array) => {
// 如果符合條件回傳 true 反之回傳 false
})
find
與 filter
很像,但只回傳第一個符合條件的值。不修改原陣列。
array.find((value, index, array) => {
// 如果符合條件回傳 true 反之回傳 false
})
let str = students.reduce((accu, name, idx) => {
return accu + name + ((idx !== students.length - 1) ? ", " : ".");
}, "Students: ");
// str: "Students: Jacob, Pascal, Jack."
let numbers = [[1,2], [3,4]];
let flatted = numbers.flat();
// flatted: [1, 2, 3, 4]
let str2 = students.join(", ");
// str2: "Jacob, Pascal, Jack"
reduce
flat
join
都是用來減少陣列的維度。三者都不會修改原陣列。reduce
應該是三者靈活度最高的,flat
跟 join
可以當 shorthand 來用。
array.reduce((accumulator, value, index, array) => {
// 一項一項的把東西合併到 accumulator
// 記得要回傳東西,做為新的 accumulator
}, initialAccumulator)
flat
用來拆高維陣列,它可以放一個參數表示拆的深度。
array.flat(depth); // depth 代表要拆的深度
join
用來把陣列變字串,同時可指定中間插入的字串。
array.join(str) // 每項元素間會加上 str
split
就是用來反向操作 join
的,回傳一分割後的陣列。
string.split(str) // str 會用來作為刀子切 string
關於物件也有幾個有用的工具。請注意,它們都是 static 所以需要在前面加上 Object.
。
// 白老鼠物件
let charlie = {
type: "unicorn",
age: 1000
}
let entries = Object.entries(charlie);
// entries: [
// ["type", "unicorn"],
// ["age", 1000]
// ]
let keys = Object.keys(charlie);
// keys: ["type", "age"]
let values = Object.values(charlie);
// values: ["unicorn", 1000]
entries
keys
values
都是用來將物件轉換成陣列用的,因為陣列有比較多好操作的方法。三者都不會修改原物件。
let fix = {
age: 500,
mood: ["angry", "tired"]
};
Object.assign(charlie, fix);
// charlie: {
// type: "unicorn",
// age: 500,
// mood: ["angry", "tired"]
// }
assign
用來複製物件內容,第一個參數是目標物件,後方參數為一或多個物件,其值會複製至目標物件。它會修改目標物件,且回傳目標物件!
Object.assign(target, source1, source2, ...); // target 會被修改
// 不想直接修改 target? 把第一個位置放 {} 就好了
let newThings = Object.assign({}, target, source1, source2, ...)
for
也常常用來遍歷陣列或物件。
直接用陣列長度及 i
來遍歷。
let arr = ["Ha", "Haha", "Lalala"];
for(let i = 0; i < arr.length; i++) { // arr.length === 3
console.log(i, arr[i]); // 0 "Ha" 1 "Haha" 2 "Lalala"
}
for of
也可以用來遍歷陣列。
let arr = ["Ha", "Haha", "Lalala"];
for(const str of arr) {
console.log(str); // "Ha" "Haha" "Lalala"
}
for in
可以用於遍歷物件的鍵 (key
)。
let charlie = {
type: "unicorn",
age: 1000
}
for(const key in charlie) {
console.log(key, charlie[key]);
}
以 9/17 12:00 ~ 9/18 12:00 文章觀看數增加值排名
+592
Day 3 雲端四大平台比較:AWS . GCP . Azure . Alibaba
+556
Day 1 無限手套 AWS 版:掌控一切的 5 + 1 雲端必學主題
+456
Day 2 AWS 是什麼?又為何企業這麼需要 AWS 人才?
+454
Day 5 網路寶石:AWS VPC 架構 Routes & Security (上)
+442
Day 4 網路寶石:AWS VPC Region/AZ vs VPC/Subnet 關係介紹
+422
Day 6 網路寶石:AWS VPC 架構 Routes & Security (下)
+420
Day 7 網路寶石:【Lab】VPC外網 Public Subnet to the Internet (IGW) (上)
+396
Day 8 網路寶石:【Lab】VPC外網 Public Subnet to the Internet (IGW) (下)
+388
Day 9 運算寶石:EC2 重點架構
+386
Day 12 運算寶石:【Lab】EC2儲存資源 EBS Volume 建立與使用 (上)
WOW!!
今天前十都是「無限手套 AWS 版:掌控一切的 5 + 1 雲端必學主題」系列!
看來大家都很愛 AWS,我是不是也該學學了?